#pragma once
#include <stdint.h>
#include "../IO/Terminal.h"
extern "C" void flush_gdt(uint32_t);
namespace System{
    
    struct gdt_entry_struct
    {
       uint16_t limit_low;           // The lower 16 bits of the limit.
       uint16_t base_low;            // The lower 16 bits of the base.
       uint8_t  base_middle;         // The next 8 bits of the base.
       uint8_t  access;              // Access flags, determine what ring this segment can be used in.
       uint8_t  granularity;
       uint8_t  base_high;           // The last 8 bits of the base.
    } __attribute__((packed));

    typedef struct gdt_entry_struct gdt_entry_t;

    struct gdt_ptr_struct
    {
        uint16_t limit;               // The upper 16 bits of all selector limits.
        uint32_t base;                // The address of the first gdt_entry_t struct.
    }__attribute__((packed));
    typedef struct gdt_ptr_struct gdt_ptr_t;


    class GlobalDescriptorTable{
    private:
        gdt_entry_t entries[5];
        gdt_ptr_t pointer;
        IO::Terminal *_terminal;
   
    public:
        GlobalDescriptorTable(IO::Terminal *terminal);
        void SetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran);
    };

}
